import StringBuilder from "../core/string-builder";
import moment from "moment";
import P from "../core/p"
import Asserts from "../core/asserts";
import LocalDateUtils from "./local-date-utils";

/**
 * 国际化使用中国的
 */
moment.locale('zh-cn');

/**
 * 定义星期名称数组
 *
 * @type {string[]}
 */
const weeks = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];

/**
 * 中文的星期名称
 *
 * @param dayOfWeek {number} 星期
 */
const chnWeek = (dayOfWeek: number): string =>{
    return weeks[dayOfWeek];
}

/**
 * 将日期格式化成字符串
 *
 * @param val - Date 对象或时间戳
 * @param pattern - 日期格式
 * @returns 格式化后的日期时间字符串
 */
const format = (val: Date | string | number, pattern: string): string => {
    return moment(new Date(val)).format(pattern);
}

/**
 * 字符串转日期
 *
 * @param str -
 * @param pattern -
 */
const parse = (str: string, pattern?: string): Date =>{
    Asserts.notBlank(str, 'input date string is undefined!');
    return moment(str, pattern).toDate();
}

/**
 * 格式化为完整日期时间字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期时间字符串
 */
const datetime = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.datetime)
}

/**
 * 格式化为日期字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const date = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.date)
}

/**
 * 格式化为日期字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const time = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.time)
}

/**
 * 格式化为紧凑日期时间字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期时间字符串
 */
const compactDatetime = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.compact_datetime)
}

/**
 * 格式化为紧凑日期字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const compactDate = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.compact_date)
}

/**
 * 格式化为紧凑日期字符串
 *
 * @param val Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const compactTime = (val: Date | string | number): string => {
    return moment(new Date(val)).format(P.compact_time)
}

/**
 * 转换为数组类型
 *
 * @param val 任意类型的值
 * @returns 转换后的数组（如果输入已经是日期则返回原数组）
 */
const caseToDate = <T>(val: unknown): Date => {
    if (Date.prototype.isPrototypeOf(val)) {
        return val;
    } else if (typeof val === 'string') {
        // 要求是标准的日期格式：2000-01-01 12:11:10
        return new Date(val);
    } else if (typeof val === 'number') {
        return new Date(val);
    } else {
        //
        return LocalDateUtils.caseToDate(val);
    }
};

/**
 * 简洁的流逝时间格式（省略不足一天的数据）
 *
 * @param millis 时间毫秒数
 * @returns 流逝时间字符串（如 "3天"）
 */
const elapsedTime = (millis: number): string => {
    const ms = Math.abs(millis);
    if (ms > 86400000) {
        return Math.round(ms / 86400000) + '天';
    } else if (ms > 3600000) {
        return Math.round(ms / 3600000) + '小时';
    } else if (ms > 60000) {
        return Math.round(ms / 60000) + '分';
    } else {
        return Math.round(ms / 1000) + '秒';
    }
}


/**
 * 完整的流逝时间格式（省略 0 值）
 *
 * @param millis 时间毫秒数
 * @returns 流逝时间字符串（如 "3天12分"）
 */
const fullyElapsedTime = (millis: number): string => {
    const builder = new StringBuilder();
    let ms = Math.abs(millis);
    let d = Math.floor(ms / 86400000);
    ms %= 86400000;
    let h = Math.floor(ms / 3600000);
    ms %= 3600000;
    let m = Math.floor(ms / 60000);
    ms %= 60000;
    let s = Math.floor(ms / 1000);
    if (d !== 0)
        builder.append(d).append('天');
    if (h !== 0)
        builder.append(h).append('小时');
    if (m !== 0)
        builder.append(m).append('分');
    if (s !== 0)
        builder.append(s).append('秒');
    return builder.build();
}

/**
 * 完整的流逝时间格式（保留 0 值）
 *
 * @param millis 时间毫秒数
 * @returns 流逝时间字符串（如 "3天0小时12分0秒"）
 */
const fullyElapsedTime2 = (millis: number): string => {
    let ms = Math.abs(millis);
    const build = new StringBuilder();
    build.append(Math.floor(ms / 86400000)).append('天');
    ms %= 86400000;
    build.append(Math.floor(ms / 3600000)).append('小时');
    ms %= 3600000;
    build.append(Math.floor(ms / 60000)).append('分');
    ms %= 60000;
    build.append(Math.floor(ms / 1000)).append('秒');
    return build.build();
}


/**
 * 通用日期格式化工具，主要是 js 中 Date 类型的相关处理
 *
 * 统一管理所有日期格式化，不要另起函数
 */
export default {
    moment

    , format

    , parse, caseToDate

    , datetime, date, time,  compactDatetime, compactDate, compactTime

    , elapsedTime, fullyElapsedTime, fullyElapsedTime2
};